package com.date;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>创建时间： 2016/5/11</p>
 * <p>描述： 时间工具类, 因预约时间都是只存HH:mm的, 所以比较处理抽象一个工具类.</p>
 *
 * @author : 　mawl
 * @version 1.0
 */
public class DateUtil {
    /**
     * 这里增加一种格式, 需要在initFormat中,增加一个case.请注意
     */
    public static final String FORMAT_OF_HM = "HH:mm";
    public static final String FORMAT_OF_HMS = "HH:mm:ss";
    public static final String FORMAT_OF_YMD = "yyyy-MM-dd";
    public static final String FORMAT_OF_YMD_HM = "yyyy-MM-dd HH:mm";
    public static final String FORMAT_OF_FULL = "yyyy-MM-dd HH:mm:ss";
    public static final String FORMAT_OF_FULL2 = "yyyyMMddHHmmss";
    public static final String FORMAT_OF_MD = "M/d";
    public static final String[] weekDays2 = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
    public static final String[] weekDays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
    public static Map<String, String> sdfMap = new HashMap<>();

    static {
        sdfMap.put(FORMAT_OF_HM, FORMAT_OF_HM);
        sdfMap.put(FORMAT_OF_HMS, FORMAT_OF_HMS);
        sdfMap.put(FORMAT_OF_YMD, FORMAT_OF_YMD);
        sdfMap.put(FORMAT_OF_YMD_HM, FORMAT_OF_YMD_HM);
        sdfMap.put(FORMAT_OF_FULL, FORMAT_OF_FULL);
        sdfMap.put(FORMAT_OF_MD, FORMAT_OF_MD);
    }

    /***
     * 获取指定日期
     * @param year
     * @param month  开始月份是0 {@link Calendar#MONTH}
     * @param day    开始日期是1 {@link Calendar#DAY_OF_MONTH}
     * @return
     */
    public static Date getDate(int year, int month, int day) {
        Calendar instance = Calendar.getInstance();
        instance.set(year, month, day);
        return instance.getTime();
    }

    public static String formatTime(Date date) {
        return formatTime(date, FORMAT_OF_YMD);
    }

    public static String formatTime(Date date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    public static Date parseDate(String time) {
        return parseDate(time, FORMAT_OF_FULL);
    }

    public static Date parseDate(String time, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            return sdf.parse(time);
        } catch (ParseException e) {
            throw new RuntimeException("解析时间时出错", e);
        }
    }

    public static Date parseDate(Date time, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        String formateTime = formatTime(time, format);
        try {
            return sdf.parse(formateTime);
        } catch (ParseException e) {
            throw new RuntimeException("解析时间时出错", e);
        }
    }

    /**
     * 比较时间before 是否在after 之前
     *
     * @param before
     * @param after
     * @return before 在after 之前 true
     * before 在after 之后或相等 false
     */
    public static boolean before(Date before, Date after, String format) {
        if (before == null || after == null) {
            throw new RuntimeException("时间比较参数不能为空.");
        }
        if (format != null && format != "") {
            format = initFormat(format);

            String date1 = formatTime(before, format);
            String date2 = formatTime(after, format);
            return before(date1, date2, format);
        } else {
            return before.before(after);
        }

    }

    public static boolean before(String before, String after, String format) {
        if (before == null || before == "" || after == "" || after == null) {
            throw new RuntimeException("时间比较参数不能为空.");
        }
        format = initFormat(format);
        Date be = parseDate(before, format);
        Date af = parseDate(after, format);
        return be.before(af);
    }

    public static boolean after(Date before, Date after, String format) {
        if (before == null || after == null) {
            throw new RuntimeException("时间比较参数不能为空.");
        }
        if (format != null && format != "") {
            format = initFormat(format);
            String date1 = formatTime(before, format);
            String date2 = formatTime(after, format);
            return after(date1, date2, format);
        } else {
            return before.after(after);
        }
    }

    public static boolean after(Date before, Date after) {
        return after(before, after, FORMAT_OF_FULL);
    }

    public static boolean after(String before, String after, String format) {
        if (before == null || before == "" || after == "" || after == null) {
            throw new RuntimeException("时间比较参数不能为空.");
        }
        format = initFormat(format);
        Date be = parseDate(before, format);
        Date af = parseDate(after, format);
        return be.after(af);
    }

    public static boolean equal(Date before, Date after) {
        return equal(before, after, FORMAT_OF_FULL);
    }

    public static boolean equal(Date before, Date after, String format) {
        if (before == null || after == null) {
            throw new RuntimeException("时间比较参数不能为空.");
        }
        format = initFormat(format);
        if (format != FORMAT_OF_FULL) {
            before = parseDate(before, format);
            after = parseDate(after, format);
        }
        return before.getTime() == after.getTime();
    }

    public static boolean notEqual(Date before, Date after, String format) {
        return !equal(before, after, format);
    }

    public static boolean beforeOrEqual(Date before, Date after, String format) {
        return before(before, after, format) || equal(before, after, format);
    }

    public static boolean beforeOrEqual(Date before, Date after) {
        return beforeOrEqual(before, after, FORMAT_OF_FULL);
    }

    public static boolean afterOrEqual(Date before, Date after, String format) {
        return after(before, after, format) || equal(before, after, format);
    }

    public static String getWeekDayChs(Calendar c) {
        if (c == null) {
            return "周一";
        }
        return weekDays[c.get(Calendar.DAY_OF_WEEK) - 1];
    }

    public static String getWeekDayChs(Date c) {
        if (c == null) {
            return "周一";
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(c);
        return getWeekDayChs(calendar);
    }

    public static int getYear(Date date) {
        if (date == null) {
            date = new Date();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }


    private static String initFormat(String format) {
        if (format == null || sdfMap.get(format) == null) {
            format = FORMAT_OF_FULL;
        }
        return format;
    }

    public static void main(String args[]) {
        Date date = getDate(2018, 1, 2);
        System.out.println(getDate(2018, 1, 2));
        System.out.println(formatTime(date, FORMAT_OF_YMD_HM));
        System.out.println(equal(parseDate(formatTime(date, FORMAT_OF_FULL), FORMAT_OF_FULL),
                                 parseDate(formatTime(date, FORMAT_OF_YMD_HM), FORMAT_OF_YMD_HM),
                                 FORMAT_OF_YMD_HM));
    }

    public static boolean isSameYear(Date before, Date after) {
        return getYear(before) == getYear(after);
    }
}
